package org.apache.sad.core.framework.utils;

public class NumberUtils {

	private static final int POSITIVE_SIGN = 0x0c;

	private static final int DEFAULT_RADIX = 10;

	private static final String ZERO = "0";

	public static String addRightPadding(String number, int len) {
		if (number == null || number.length() >= len) {
			return number;
		}

		StringBuffer result = new StringBuffer(number);
		for (int i = 0; i < (len - number.length()); i++) {
			result.append(ZERO);
		}
		return result.toString();
	}

	public static String zeroPad(long number, int len) {
		return String.format("%0" + len + "d", number);
	}

    public static String addPadding(String number, int len) {
        if (number == null || number.length() >= len) {
            return number;
        }

        StringBuffer result = new StringBuffer(number);
        for (int i = 0; i < (len - number.length()); i++) {
            result.insert(0, ZERO);
        }
        return result.toString();
    }

	public static byte[] addPositiveSignToUnsignedPackedDecimal(byte[] packed,
			int offset, int length) {
		int carryNibble = 0x00;
		int tmpNibble;

		// first make room for the sign nibble by shifting everything over by
		// one nibble
		for (int i = offset + length - 1; i >= offset; --i) {

			// save high order nibble
			tmpNibble = packed[i] >> 4;

			// shift low nibble over to the high nibble
			packed[i] = (byte) (packed[i] << 4);

			// set the low nibble to the carry nibble
			packed[i] = (byte) (packed[i] | carryNibble);

			// save carry nibble
			carryNibble = tmpNibble;

		}

		// add the sign nibble
		packed[offset + length - 1] = (byte) ((int) packed[offset + length - 1] | POSITIVE_SIGN);

		return packed;
	}

	public static long unsignedPackedToLong(byte[] packed, int offset, int length, int radix) {
		int highNibble;
		int lowNibble;

		long total = 0;
		int multiplier = 1;

		for (int i = offset + length - 1; i >= offset; --i) {

			// split current byte into high and low nibble
			// need mask to keep unsigned bytes
			highNibble = (packed[i] & 0xff) >> 4;
			lowNibble = (packed[i] & 0xff) & 0x0f;

			// add high and low nibble values to total
			if (lowNibble >= 0) {
				total += ((int) lowNibble) * multiplier;
				multiplier *= radix;
			}
			if (highNibble >= 0) {
				total += ((int) highNibble) * multiplier;
				multiplier *= radix;
			}
		}

		return total;
	}

}